import data
from services import cityService, weeklyWeatherService
import numpy as np

import pandas as pd
from sklearn.cluster import KMeans
import joblib


def kMeansTrain():
    """
    聚类训练
    """
    dataCSV = pd.read_csv("dataset/weather.csv")
    datas = []
    for value in dataCSV.values:
        maxTemp = value[2][:-1]
        minTemp = value[3][:-1]
        if maxTemp != '' and minTemp != '':
            datas.append({"maxTemp": int(maxTemp), "minTemp": int(minTemp)})
    df = pd.DataFrame(datas)

    # 选择特征
    features = ["maxTemp", "minTemp"]

    # 数据预处理
    df = df.dropna()
    df[features] = df[features].astype("float")

    # 初始化 K-means 模型
    kmeans = KMeans(n_clusters=4, n_init=10000)

    # 训练模型
    kmeans.fit(df[features])
    # 保存模型
    joblib.dump(kmeans, "kmeans_model.pkl")


def kMeansGetStatus(dataList: list) -> list[int]:
    # 导入数据
    df = pd.DataFrame([{"maxTemp": data['avgMaxTemp'], "minTemp": data['avgMinTemp']} for data in dataList])

    # 选择特征
    features = ["maxTemp", "minTemp"]

    # 数据预处理
    df = df.dropna()
    df[features] = df[features].astype("float")

    # 加载模型
    kmeans = joblib.load("kmeans_model.pkl")

    # 进行聚类分析
    labels = kmeans.predict(df)

    # # 显示聚类结果
    # print(labels)

    return labels


def getMid(data):
    """
    获取中间值
    :param data:
    """
    data.sort()
    half = len(data) // 2
    return (data[half] + data[~half]) / 2


def analyseProvince(provinceId: int) -> list:
    citys = cityService.list(whereColumns=['province_id'], whereValues=[provinceId])
    ret = []

    for city in citys:
        # 获取城市的每周天气数据
        weeklyList = data.getWeeklyWeather(city.id)

        # 获取城市的每周天气数据中的最低温度和最高温度
        minTempList = [int(w.minTemp) for w in weeklyList]
        maxTempList = [int(w.maxTemp) for w in weeklyList]

        # 获取城市的每周天气数据中的平均最低温度和平均最高温度
        minTemp = np.min(minTempList)
        maxTemp = np.max(maxTempList)

        # 获取城市的每周天气数据中的平均最低温度和平均最高温度
        avgMinTemp = round(np.mean(minTempList), 2)
        avgMaxTemp = round(np.mean(maxTempList), 2)

        # 获取城市的每周天气数据中的中间最低温度和中间最高温度
        midMinTemp = round(getMid(minTempList), 2)
        midMaxTemp = round(getMid(maxTempList), 2)

        # 获取城市的每周天气数据中的方差最低温度和方差最高温度
        varMinTemp = round(np.var(minTempList), 2)
        varMaxTemp = round(np.var(maxTempList), 2)

        ret.append({
            'id': city.id,
            'name': city.name,
            'minTemp': minTemp,
            'maxTemp': maxTemp,
            'avgMinTemp': avgMinTemp,
            'avgMaxTemp': avgMaxTemp,
            'midMinTemp': midMinTemp,
            'midMaxTemp': midMaxTemp,
            'varMinTemp': varMinTemp,
            'varMaxTemp': varMaxTemp,
            'status': '未知'
        })

    statusList = kMeansGetStatus(ret)

    statusMapping = ['炎热', '凉爽', '舒适', '寒冷']

    for i, e in enumerate(statusList):
        ret[i]['status'] = statusMapping[e]

    return ret
